package com.zjw.zy.common;

import android.view.MotionEvent;

import androidx.annotation.NonNull;

/**
 * @author ：zhong.jw
 * @date ：Created in 2023/2/23 13:39
 * 旋转手势相关:采用向量法计算角度
 */
public final class RotateGestureDetector {

    private static final double DEFAULT_LIMIT_START = 3f;

    @NonNull
    private final Listener listener;

    /**
     * 是否旋转中
     */
    public boolean isRotating = false;
    /**
     * 旋转轴点x
     */
    public int focusX;
    /**
     * 旋转轴点y
     */
    public int focusY;
    /**
     * 欧拉角，范围[-180~180]
     */
    public double eulerAngle = 0;

    /**
     * 弧度
     */
    public double radian = 0;

    /**
     * 开始旋转的初始向量x值
     */
    public double x1 = 0;
    /**
     * 开始旋转的初始向量y值
     */
    public double y1 = 0;
    /**
     * 开始旋转的初始向量斜率
     */
    public double k1 = 0;

    public RotateGestureDetector(@NonNull Listener listener) {
        this.listener = listener;
    }


    public boolean onTouchEvent(MotionEvent event) {

        int action = event.getActionMasked();
        int pointCount = event.getPointerCount();

        if ((action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_POINTER_DOWN) && (pointCount == 2) && !isRotating) {
            double e1x = event.getX(0);
            double e2x = event.getX(1);
            double e1y = event.getY(0);
            double e2y = event.getY(1);
            focusX = (int) (e1x + e2x) / 2;
            focusY = (int) ((e1y + e2y) / 2);
            x1 = e2x - e1x;
            y1 = e2y - e1y;
            k1 = y1 / x1;
            return true;
        }

        if (action == MotionEvent.ACTION_MOVE && pointCount == 2) {
            double e1x = event.getX(0);
            double e2x = event.getX(1);
            double e1y = event.getY(0);
            double e2y = event.getY(1);
            double x2 = e2x - e1x;
            double y2 = e2y - e1y;
            //angle = arccos(ab/(|a||b|))
            radian = Math.acos((x1 * x2 + y1 * y2) / (Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2)) * Math.sqrt(Math.pow(x2, 2) + Math.pow(y2, 2))));
            // y = k1*x2 > y2 来判断是否属于外角
            eulerAngle = (radian / Math.PI * 180) * (k1 * x2 > y2 ? -1 : 1);
            if (isRotating) {
                listener.onRotating(this);
            }

            if (Math.abs(eulerAngle) >= DEFAULT_LIMIT_START) {
                isRotating = true;
                listener.onRotateStart(this);
            }

            return true;
        }


        if ((action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) && isRotating) {
            isRotating = false;
            listener.onRotateEnd(this);
        }

        return true;
    }

    public interface Listener {

        /**
         * @param detector:旋转信息
         */
        void onRotateStart(RotateGestureDetector detector);

        /**
         * @param detector:旋转信息
         */
        void onRotating(RotateGestureDetector detector);

        /**
         * @param detector:旋转信息
         */
        void onRotateEnd(RotateGestureDetector detector);
    }

}
